from django.http import JsonResponse
from backend.cews.services import LogService
from drf_spectacular.utils import extend_schema, inline_serializer
from rest_framework import serializers
from rest_framework import status as ResponseStatus
from rest_framework.decorators import action
from rest_framework.mixins import (CreateModelMixin, ListModelMixin,
                                   RetrieveModelMixin, UpdateModelMixin)
from rest_framework.response import Response
from rest_framework.viewsets import GenericViewSet
from utils.autoschema import AutoDocSchema, custom_response_serailizer
from utils.decorators import error_response, request_data, activities_logging

import backend.cews.services.RepairService as RepairService
from backend.cews.models import (Asset, Parts, RepairAction, RepairOrder,
                                 RepairOrderRepairDetails, System, Log, Equipment,
                                 Workgroup, Line, DepotList)
from backend.cews.services import CheckOutService
from backend.cews.services.VersionService import query_current_latest_version

from utils.mixins import RepairOrderModelMixin as RetrieveModelMixin
from utils.mixins import RepairOrderUpdateModelMixin as UpdateModelMixin

from .serializers import (OrderPartSearchSerializer, PartsSerializer,
                          RepairActionSerializer,
                          RepairOrderInspectionSerializer,
                          RepairOrderMaintenanceHistorySerializer,
                          RepairOrderPartSerializer,
                          RepairOrderPartsHardTimeReplacementSerializer,
                          RepairOrderRepairDetailsSerializer,
                          RepairOrderSerializer, StockItemSerializer,
                          VersionCurrentLatestSerailizer)
import json


class RepairViewSet(
    RetrieveModelMixin,
    ListModelMixin,
    UpdateModelMixin,
    GenericViewSet,
    CreateModelMixin
):

    serializer_class = RepairOrderSerializer
    queryset = RepairOrder.objects.all()

    @extend_schema(responses={200: RepairActionSerializer(many=True)})
    @action(
        detail=False, methods=["POST"], url_name="get_repair_action",
        schema=AutoDocSchema()
    )
    @request_data(keys=["id"], types={"id": int})
    def get_repair_action(self, request, id):
        '''
        desc: Get list of repair actions for a repair order
        json:
            id: number
        '''
        result_set = RepairAction.objects.get(pk=id)
        serializer = RepairActionSerializer(result_set)
        return Response(
            status=ResponseStatus.HTTP_200_OK,
            data=serializer.data
        )

    @action(
        detail=False, methods=["POST"], url_name="create_repair_order",
        schema=AutoDocSchema()
    )
    @request_data(
        keys=[
            "stock_code",
            "serial_no",
            'work_order_no',
            'mtce_type',
            'report_date',
            'location',
            'department',
            'failure_symptom',
            'remark',
            'status',
            'io_counter',
            'workgroup',
            'parent_work_order_no',
            'eqpt_description',
            'check_in_date',
            'equipment',
            'line',
            'line_work_order',
            'delay_i',
            'delay_a',
            'contractor_liability',
            'dlc_form_no',
            'designated_person_name',
            'date',
            'po_no',
            'inspection_no',
            'received_date',
        ],
        types={"serial_no": str},
        optional=['work_order_no',
                  'io_counter',
                  'remark',
                  'contractor_liability',
                  'dlc_form_no',
                  'designated_person_name',
                  'date',
                  'workgroup',
                  'line',
                  'line_work_order',
                  'delay_i',
                  'delay_a',
                  'po_no',
                  'inspection_no',
                  'received_date',
                  ]
    )
    def create_repair_order(
        self,
        request,
        stock_code,
        serial_no,
        mtce_type,
        report_date,
        location,
        department,
        failure_symptom,
        status,
        parent_work_order_no,
        eqpt_description,
        check_in_date,
        equipment,
        line='',
        line_work_order='',
        delay_i='',
        delay_a='',
        remark='',
        io_counter='',
        workgroup='',
        work_order_no='',
        contractor_liability='',
        dlc_form_no='',
        designated_person_name='',
        date='',
        po_no='',
        inspection_no='',
        received_date='',
    ):
        '''
            desc: create a repair order for a check-in part
            json:
                stock_code: string
                serial_no:
                    type: string
                    description: serial number of the part
                work_order_no: string
                mtce_type: string
                report_date: string
                location: string
                department: string
                failure_symptom: string
                remark: string
                status: string
                parent_work_order_no: string
                io_counter: string
                workgroup: string
                contractor_liability: string
                dlc_form_no: string
                designated_person_name: string
                date: string
            response:
                "200":
                    qr_code: object
                    repair_order_id: number
                    repair_part_id: number
        '''


        # pass the parameter to function
        try:
            order, order_part, _ = \
                RepairService.create_repair_order(
                    stock_code,
                    serial_no,
                    work_order_no,
                    mtce_type,
                    report_date,
                    location,
                    department,
                    failure_symptom,
                    remark,
                    status,
                    parent_work_order_no,
                    eqpt_description,
                    check_in_date,
                    equipment,
                    line,
                    line_work_order,
                    delay_i,
                    delay_a,
                    io_counter,
                    workgroup,
                    contractor_liability,
                    dlc_form_no,
                    designated_person_name,
                    date,
                    po_no,
                    inspection_no,
                    received_date,
                    request.user
                )

            # create qr code
            # It will be generated after the maintenance order is created.
            # It stored information of order number, Check-In date and time.
            qr_code = {
                "Order Number": order.order_no,
                "Check-in Date": order.check_in,
                # "Check-in Time": order.check_in
            }

            return Response(
                status=ResponseStatus.HTTP_200_OK,
                data={
                    "qr_code": qr_code,
                    "order_id": order.id,
                    "order_part_id": order_part.id
                }
            )
        except Parts.DoesNotExist as ex:
            return Response(
                status=ResponseStatus.HTTP_400_BAD_REQUEST,
                data={
                    'code': 0,
                    "message": str(ex)
                }
            )
        except ValueError as e:
            return Response(
                status=ResponseStatus.HTTP_400_BAD_REQUEST,
                data={
                    'code': 0,
                    "message": str(e)
                }
            )


    @action(
        detail=False, methods=["POST"], url_name="check_create_parts_order_exists",
        schema=AutoDocSchema()
    )
    @request_data(
        keys=[
            "stock_code",
            "serial_no",
        ],
        types={"serial_no": str, "stock_code": str},
    )
    def check_create_parts_order_exists(self, request, stock_code, serial_no):
        if msg := RepairService.check_create_parts_order_exists(stock_code, serial_no):
            return Response(status=200, data={"code": 0,"data": False, "message": msg})
        return Response(status=200, data={"code": 1,"data": True,"message": "ok"})


    @extend_schema(responses={200: OrderPartSearchSerializer(many=True)})
    @action(
        detail=False, methods=["POST"], url_name="get_order_parts",
        schema=AutoDocSchema()
    )
    @request_data(
        keys=[
            "stock_code",
            "serial_no",
            "checkin_status",
            "checkout_status",
            "complete_status", 
            "status",
            "mtce_type",
            "short_description"
        ],
        types={
            "serial_no": str,
            "stock_code": str,
            "checkin_status": bool,
            "checkout_status": bool,
            "complete_status": bool,
            "mtce_type": str,
            "status": str,
            "short_description": str
        }
    )
    def get_order_parts(
        self,
        request,
        serial_no,
        stock_code,
        checkin_status,
        checkout_status,
        complete_status,
        mtce_type,
        status,
        short_description
    ):
        '''
            desc: Get order part.

            json:
                stock_code: string
                serial_no: string
                checkin_status: boolean
                checkout_status: boolean
                complete_status: boolean
        '''
        result_set = RepairService.get_order_parts(
            stock_code,
            serial_no,
            status,
            mtce_type=mtce_type,
            short_description=short_description,
            complete_status=complete_status,
        )


        serializer = OrderPartSearchSerializer(result_set, many=True)
        data = serializer.data
        if data:
            data = sorted(list(data), key=lambda x: x['repair_order']['check_in'])
        return Response(
            status=ResponseStatus.HTTP_200_OK,
            data=data
        )

    @extend_schema(responses={200: OrderPartSearchSerializer(many=True)})
    @action(
        detail=False, methods=["POST"], url_name="get_can_checkout_parts",
        schema=AutoDocSchema()
    )
    @request_data(
        keys=[
            "stock_code",
            "serial_no",
        ],
        types={
            "serial_no": str,
            "stock_code": str,
        }
    )
    def get_can_checkout_parts(
        self,
        request,
        serial_no,
        stock_code,
    ):
        '''
            desc: Get parts that can checkout.

            json:
                stock_code: string
                serial_no: string
        '''
        result_set = RepairService.get_can_checkout_parts(
            stock_code,
            serial_no
        )

        serializer = OrderPartSearchSerializer(result_set, many=True)
        return Response(
            status=ResponseStatus.HTTP_200_OK,
            data=serializer.data
        )

    @extend_schema(responses={200: RepairOrderPartSerializer(many=True)})
    @action(
        detail=False, methods=["POST"], url_name="get_repair_order_parts",
        schema=AutoDocSchema()
    )
    @request_data(
        keys=['repair_order_id'],
        types={"repair_order_id": int}
    )
    def get_repair_order_parts(self, request, repair_order_id):
        '''
            desc: Get repair order parts of a order.
        '''
        result_set = RepairService.get_repair_order_parts(repair_order_id)
        serializer = RepairOrderPartSerializer(result_set, many=True)
        return Response(
            status=ResponseStatus.HTTP_200_OK,
            data=serializer.data
        )

    @extend_schema(
        responses=custom_response_serailizer(
            VersionCurrentLatestSerailizer(many=True)
        )
    )
    @action(
        detail=False, methods=["POST"], url_name="get_all_version",
        schema=AutoDocSchema(),
    )
    @request_data(keys=["repair_order_id"], types={"repair_order_id": int})
    @error_response(ValueError, RepairOrder.DoesNotExist)
    def get_all_version(self, request, repair_order_id):
        '''
            desc:
                Get all repair order part sw and hw version list with latest
                version `(from version master)`.
        '''
        data = query_current_latest_version(repair_order_id)
        return Response(
            data={
                'code': 1,
                'data': data
            },
            status=ResponseStatus.HTTP_200_OK
        )

    @extend_schema(
        responses={
            200: StockItemSerializer(many=True)
        }
    )
    @action(
        detail=False, methods=["POST"], url_name="get_part_detail",
        schema=AutoDocSchema()
    )
    @request_data(keys=["stock_code"], types={"stock_code": str})
    def get_part_detail(self, request, stock_code):
        '''
            desc: Get part detail

            json:
                stock_code: string

        '''
        result_set = RepairService.get_part_detail(stock_code)
        serializer = StockItemSerializer(result_set, many=True)
        return Response(
            status=ResponseStatus.HTTP_200_OK,
            data=serializer.data
        )
    
    @activities_logging(
        log_type=Log.LogType.MAINTENANCE,
        category_type=Log.CategoryType.ORDER,
        action_type=Log.ActionType.FITMENT,
        action="fitment",
        description="repair order fitment"
    )
    @action(
        detail=False, methods=["POST"], url_name="fitment",
        schema=AutoDocSchema()
    )
    @request_data(
        keys=[
            "repair_order_id",
            "repair_order_part_id",
            "serial_no",
        ],
        types={
            "repair_order_id": int,
            "repair_order_part_id": int,
            "serial_no": str,
        },
    )
    def fitment(
        self,
        request,
        repair_order_id,
        repair_order_part_id,
        serial_no
    ):
        '''
            desc: Repair order part fitment

            json:
                repair_order_part_id: number
                serial_no: string

            responses:
                "200":
                    code: number
                    message: string
        '''
        response = {
            "code": 0,
            "message": "Fitment failed."
        }

        try:
            fitment_status = RepairService.fitment(
                repair_order_part_id,
                serial_no
            )

            if fitment_status:
                response = {
                    "code": 1,
                    "message": "Fitment success!"
                }

            return Response(
                status=ResponseStatus.HTTP_200_OK,
                data=response
            )
        except ValueError as ex:
            return Response(
                status=ResponseStatus.HTTP_400_BAD_REQUEST,
                data={
                    'code': 0,
                    "message": str(ex)
                }
            )

    @activities_logging(
        log_type=Log.LogType.MAINTENANCE,
        category_type=Log.CategoryType.HARDTIME,
        action_type=Log.ActionType.DELETE,
        action="delete_order_replacement_task",
        description="delete repair order replacement task"
    )
    @action(
        detail=False, methods=["POST"], url_name="delete_order_replacement_task",
        schema=AutoDocSchema()
    )
    @request_data(
        keys=[
            "replacement_task_id",
        ],
        types={
            "replacement_task_id": int,
        },
    )
    def delete_order_replacement_task(
        self,
        request,
        replacement_task_id
    ):
        '''
            desc: Delete replacment task in order

            json:
                replacement_task_id: number

            responses:
                "200":
                    code: number
                    message: string
        '''
        response = {
            "code": 0,
            "message": "Failed to delete"
        }

        delete_status = RepairService.delete_order_one_time_replacement_task(
            replacement_task_id
        )

        if delete_status:
            response = {
                "code": 1,
                "message": "Delete success!"
            }

        return Response(
            status=ResponseStatus.HTTP_200_OK,
            data=response
        )
    
    @activities_logging(
        log_type=Log.LogType.MAINTENANCE,
        category_type=Log.CategoryType.ORDER,
        action_type=Log.ActionType.DEFITMENT,
        action="defitment",
        description="repair order defitment"
    )
    @action(
        detail=False, methods=["POST"], url_name="defitment",
        schema=AutoDocSchema()
    )
    @request_data(
        keys=[
            "repair_order_part_id",
        ],
        types={
            "repair_order_part_id": int,
        },
    )
    def defitment(
        self,
        request,
        repair_order_part_id
    ):
        '''
            desc: Repair order part defitment

            json:
                repair_order_part_id: number

            responses:
                "200":
                    code: number
                    message: string
        '''
        response = {
            "code": 0,
            "message": "Defitment failed."
        }

        defitment_status = RepairService.defitment(
            repair_order_part_id
        )

        if defitment_status:
            response = {
                "code": 1,
                "message": "Defitment success!"
            }

        return Response(
            status=ResponseStatus.HTTP_200_OK,
            data=response
        )

    @extend_schema(
        responses={
            200: RepairOrderMaintenanceHistorySerializer(many=True)
        }
    )
    @action(
        detail=False, methods=["POST"], url_name="get_maintenance_history",
        schema=AutoDocSchema()
    )
    @request_data(
        keys=["repair_order_id"]
    )
    def get_maintenance_history(
        self,
        request,
        repair_order_id
    ):
        '''
            desc: Get maintenance history

            json:
                repair_order_id: number
        '''

        serializer = RepairOrderMaintenanceHistorySerializer(
            RepairService.get_maintenance_history(
                repair_order_id=repair_order_id
            ),
            many=True
        )

        return Response(
            status=ResponseStatus.HTTP_200_OK,
            data=serializer.data
        )

    @action(detail=False, methods=['post'], schema=AutoDocSchema(),
            url_name='check_status')
    @request_data(keys=['repair_order_id'])
    @error_response()
    def check_status(self, request, repair_order_id):
        '''
            desc: >
                Check status of a repair order

                ## Response

                ```

                {
                    "part_detail":{
                        "outstanding":0,
                        "message":[]
                    },
                    "current_task":{
                        "outstanding":0,
                        "message":[],
                    },
                    "software":{
                        "outstanding":0,
                        "message":[],
                    },
                    "hardware":{
                        "outstanding":0,
                        "message":[],
                    },
                    "edoc":{
                        "outstanding":0,
                        "message":[],
                    },
                    "hard_time_replacement":{
                        "outstanding":0,
                        "message":[],
                    },
                    "final_check":{
                        "outstanding":0,
                        "message":[],
                    }
                }

                ```

        '''
        return Response(
            status=ResponseStatus.HTTP_200_OK,
            data=CheckOutService.check_all_status(repair_order_id)
        )

    @extend_schema(responses=PartsSerializer)
    @action(detail=False, methods=['post'], schema=AutoDocSchema())
    @request_data(keys=['repair_order_id'], types={'repair_order_id': int})
    @error_response()
    def get_primary_part(self, request, repair_order_id):
        repair_order = RepairOrder.objects.get(id=repair_order_id)
        primary_part = repair_order.primary_part
        part = primary_part.part

        return Response(data=PartsSerializer(part).data, status=200)

    @action(
        detail=False,
        methods=['post'],
        schema=AutoDocSchema(),
        url_name='job_complete',
        url_path='job_complete'
    )
    @request_data(
        keys=['repair_order_id', 'force','qrcode','username','password'],
        types={'repair_order_id': int, 'force': bool},
        optional=['qrcode','username','password']
    )
    @error_response()
    def job_complete_api(self, request, repair_order_id, force,qrcode=None,username=None,password=None):
        print(qrcode)
        res, status = CheckOutService.job_complete(
            repair_order_id,
            request.user,
            force,
            qrcode=qrcode,
            username=username,
            password=password
        )
        RepairService.update_repair_order_last_action_date(repair_order_id)

        if res:
            return JsonResponse(
                data={
                    'code': 1,
                    'message': 'Job complete successfully',
                },
                status=200
            )

        messages = []

        for k, v in status.items():
            if v['message']:
                messages.extend(v['message'])

        return JsonResponse(
            data={
                'code': 0,
                'message': 'Job complete failed',
                'data': messages
            },
            status=200
        )

    @action(detail=False, methods=['get'], schema=AutoDocSchema())
    @request_data(keys=[])
    @error_response()
    def input_option(self, request):
        ret = {}
        system = System.objects.all()
        eq_class = Equipment.objects.filter(deleted=False)
        eq_class_4 = Equipment.objects.filter(deleted=False).exclude(description='lv5')
        eq_class_5 = Equipment.objects.filter(description='lv5',deleted=False)
        workgroups = Workgroup.objects.all()
        lines = Line.objects.all()
        depots = DepotList.objects.all()

        ret['system'] = [s.system for s in system]
        ret['equipmentClass'] = [c.equipment_class for c in eq_class]
        ret['equipmentClassLv4'] = [c.equipment_class for c in eq_class_4]
        ret['equipmentClassLv5'] = [c.equipment_class for c in eq_class_5]
        ret['workgroup'] = [c.workgroup for c in workgroups]
        ret['line'] = [c.name for c in lines]
        ret['depot'] = [c.depot for c in depots]

        asset = Asset.objects.all()

        ret['lv1'] = []
        ret['lv2'] = []
        ret['lv3'] = []
        ret['lv4'] = []
        ret['lv5'] = []
        ret['lv6'] = []

        for a in asset:
            if a.level > 6 or a.level < 1:
                continue

            key = 'lv' + str(a.level)
            ret[key].append(a.asset)

        return Response(data=ret, status=200)

    @activities_logging(
        log_type=Log.LogType.MAINTENANCE,
        category_type=Log.CategoryType.HARDTIME,
        action_type=Log.ActionType.CREATE,
        action="create_replacement_task",
        description="create repair order replacement task"
    )
    @action(
        detail=False,
        methods=["POST"],
        url_name="create_replacement_task",
        schema=AutoDocSchema()
    )
    @request_data(
        keys=[
            "repair_order_part_id",
            "repair_order_id",
            "component"
        ],
        types={
            "repair_order_part_id": int,
            "repair_order_id": int,
            "component": str
        },
    )
    def create_replacement_task(
        self,
        request,
        repair_order_part_id,
        repair_order_id,
        component
    ):
        '''
            desc: Create replacement task for order

            json:
                repair_order_part_id: int
                repair_order_id: int
                component: string

            responses:
                "200":
                    code: number
                    message: string
        '''
        response = {
            "code": 0,
            "message": "Failed to create new replacement task."
        }

        if RepairService.create_replacement_task(
            repair_order_id,
            repair_order_part_id,
            component
        ):
            response = {
                "code": 1,
                "message": "New replacement created."
            }

        return Response(
            status=ResponseStatus.HTTP_200_OK,
            data=response
        )

    @activities_logging(
        log_type=Log.LogType.MAINTENANCE,
        category_type=Log.CategoryType.ORDER,
        action_type=Log.ActionType.FITMENT,
        action="confirm_repair_order",
        description="Confirm repair order part childs"
    )
    @action(
        detail=False,
        methods=["POST"],
        url_name="confirm_repair_order",
        schema=AutoDocSchema()
    )
    @request_data(
        keys=[
            "repair_order_id",
            "check",
        ],
        types={
            "repair_order_id": int,
            "check": int
        },
    )
    def confirm_repair_order(
        self,
        request,
        repair_order_id,
        check
    ):
        '''
            desc: Confirm repair order

            json:
                repair_order_id: number
                check: number

            responses:
                "200":
                    code: number
                    message: string
        '''
        response = {
            "code": 0,
            "message": "Failed to confirm."
        }
        RepairService.update_repair_order_last_action_date(repair_order_id)


        if RepairService.confirm_repair_order(
            repair_order_id,
            check
        ):
            response = {
                "code": 1,
                "message": "Confirmed."
            }

        return Response(
            status=ResponseStatus.HTTP_200_OK,
            data=response
        )

    @activities_logging(
        log_type=Log.LogType.MAINTENANCE,
        category_type=Log.CategoryType.HARDTIME,
        action_type=Log.ActionType.UPDATE,
        action="update_replacement_task",
        description="update repair order replacement task"
    )
    @action(
        detail=False,
        methods=["POST"],
        url_name="update_replacement_task",
        schema=AutoDocSchema()
    )
    @request_data(
        keys=[
            "repair_order_replacement_id",
            "completed",
            "update_time"
        ],
        types={
            "repair_order_replacement_id": int,
            "completed": bool,
            "update_time": str
        },
    )
    def update_replacement_task(
        self,
        request,
        repair_order_replacement_id,
        completed,
        update_time
    ):
        '''
            desc: Update repair replacement task

            json:
                repair_order_replacement_id: number
                completed: bool
                update_time : string

            responses:
                "200":
                    code: number
                    message: string
        '''
        response = {
            "code": 0,
            "message": "Failed to update."
        }

        if RepairService.update_replacement_task(
            repair_order_replacement_id,
            completed,
            update_time
        ):
            response = {
                "code": 1,
                "message": "Confirmed."
            }

        return Response(
            status=ResponseStatus.HTTP_200_OK,
            data=response
        )

    @activities_logging(
        log_type=Log.LogType.MAINTENANCE,
        category_type=Log.CategoryType.ORDER,
        action_type=Log.ActionType.FITMENT,
        action="update_fitment",
        description="update repair order part fitment"
    )
    @action(
        detail=False,
        methods=["POST"],
        url_name="update_fitment",
        schema=AutoDocSchema()
    )
    @request_data(
        keys=[
            "repair_order_part_id",
        ],
        types={
            "repair_order_part_id": int,
        },
    )
    def update_fitment(
        self,
        request,
        repair_order_part_id,
    ):
        '''
            desc: Update fitment for repair order

            json:
                repair_order_part_id: number

            responses:
                "200":
                    code: number
                    message: string
        '''

        RepairService.update_fitment(
            repair_order_part_id,
        )

        return Response(
            status=ResponseStatus.HTTP_200_OK,
            data={
                "code": 1,
                "message": "Fitment updated."
            }
        )

    @activities_logging(
        log_type=Log.LogType.MAINTENANCE,
        category_type=Log.CategoryType.PART,
        action_type=Log.ActionType.CHECKOUT,
        action="checkout",
        description="Check out part"
    )
    @extend_schema(responses={
        200: inline_serializer(
            name='checkout_api_inline',
            fields={
                'code': serializers.IntegerField(),
                'message': serializers.CharField()
            }
        )
    })
    @action(detail=False, methods=['post'], schema=AutoDocSchema())
    @request_data(keys=['repair_order_id','workgroup'])
    @error_response()
    def checkout(self, request, repair_order_id, workgroup):
        '''
            desc: code 1 means checkout successfully, code 0 means checkout failed
        '''
        res = CheckOutService.checkout(repair_order_id, workgroup, request.user.username)

        return Response(
            data={
                'message':'Checkout successfully' if res else 'Checkout failed',
                'code': 1 if res else 0
            }
        )

    @extend_schema(
        responses={
            200: RepairOrderPartsHardTimeReplacementSerializer(many=True)
        }
    )
    @action(
        detail=False, methods=["POST"], url_name="get_hard_time_replacement",
        schema=AutoDocSchema()
    )
    @request_data(
        keys=["repair_order_id"]
    )
    def get_hard_time_replacement(
        self,
        request,
        repair_order_id
    ):
        '''
            desc: Get hard time replacement from repair order parts.

            json:
                repair_order_id: number
        '''
        serializer = RepairOrderPartsHardTimeReplacementSerializer(
            RepairService.get_hard_time_replacement(
                repair_order_id
            ),
            many=True
        )

        return Response(
            status=ResponseStatus.HTTP_200_OK,
            data=serializer.data
        )
        
    
    @extend_schema(
        responses={
            200: RepairOrderInspectionSerializer(many=False)
        }
    )
    @action(
        detail=False, methods=["POST"], url_name="get_contractor_liability",
        schema=AutoDocSchema()
    )
    @request_data(
        keys=["repair_order_id"]
    )
    def get_contractor_liability(
        self,
        request,
        repair_order_id
    ):
        '''
            desc: Get contractor liability from repair order inspection.

            json:
                repair_order_id: number
        '''
        serializer = RepairOrderInspectionSerializer(
            RepairService.get_repair_order_inspection(
                repair_order_id
            ),
            many=False
        )

        return Response(
            status=ResponseStatus.HTTP_200_OK,
            data=serializer.data
        )

    @extend_schema(responses={200: RepairOrderRepairDetailsSerializer})
    @action(detail=False, methods=['get'], schema=AutoDocSchema())
    @request_data(keys=['repair_order_id'],request_attr='GET')
    @error_response()
    def get_repair_order_details(self,request,repair_order_id):
        print(repair_order_id)
        detail = RepairOrderRepairDetails.objects.filter(repair_order_id=repair_order_id).first()
        lizer = RepairOrderRepairDetailsSerializer(detail,context={
        'request': request
    })
        data = lizer.data
        return Response(data=data)
    
    @extend_schema(responses={200: RepairOrderRepairDetailsSerializer})
    @action(detail=False, methods=['post'], schema=AutoDocSchema())
    @request_data(keys=[
        'repair_order_id',
        'repair_details',
        'failure_symptom',
        'actions',
        'remarks',
        'delivery_to',
        'scrapped',
        'deleted',
        'fault_equipment',
        'maintenance_type',
        'test_result',
        'maintenance_details',
        'spare_part',
        'repeat_within_six_months',
    ],optional=[
        'repair_details',
        'failure_symptom',
        'actions',
        'remarks',
        'delivery_to',
        'scrapped',
        'deleted',
        'maintenance_type',
        'maintenance_details',
        'spare_part',
        'repeat_within_six_months',
    ],types={
        'scrapped':bool,
        'deleted':bool,
        
    })
    @error_response()
    def update_repair_order_details(self,request,
        repair_order_id,
        fault_equipment,
        test_result,
        maintenance_type='',
        repair_details=False,
        failure_symptom=False,
        actions=False,
        remarks=False,
        delivery_to=False,
        scrapped=False,
        deleted=False,
        maintenance_details='',
        spare_part='',
        repeat_within_six_months=''
    ):
        '''
            desc: partial update of Repair
        '''
        repair_order = RepairOrder.objects.filter(id=repair_order_id).first()
        if repair_order.status == 'COMPLETE' or repair_order.status == 'COMPLETE*':
            if not request.user.has_perm('cews.can_change_repair_detail_after_job_complete'):
                raise ValueError('User has no permission to change repair detail after job completed.')
        
        instance = RepairOrderRepairDetails.objects.filter(repair_order_id=repair_order_id).first()
        
        if not instance:
            raise ValueError('RepairOrderRepairDetails not found')
                
        data = {
            'repair_order': repair_order.pk,
            'fault_equipment': fault_equipment,
            'test_result': test_result
        }
        description = 'update '
        ## add feilds into data if they are not false
        if 'repair_details':
            data['repair_details'] = repair_details
            description += f"repair details: {repair_details} "
        if 'failure_symptom':
            data['failure_symptom'] = failure_symptom
            description += f"failure symptom: {failure_symptom} "
        if 'actions':
            data['actions'] = actions
            description += f"actions: {actions} "
        if 'remarks':
            data['remarks'] = remarks
            description += f"remarks: {remarks} "
        if 'delivery_to':
            data['delivery_to'] = delivery_to
            description += f"delivery to: {delivery_to} "
            r = RepairOrder.objects.get(pk=repair_order_id)
            r.deliver_to = delivery_to
            r.save()
        if 'scrapped':
            data['scrapped'] = scrapped
            description += f"scrapped: {scrapped} "
        if 'maintenance_type':
            data['maintenance_type'] = maintenance_type
            description += f"maintenance type: {maintenance_type} "
        if 'deleted':
            data['deleted'] = deleted
            description += f"deleted: {deleted} "

        # if 'test_result':
        #     data['test_result'] = test_result
        #     description += f"test result: {test_result} "

        if 'maintenance_details':
            data['maintenance_details'] = maintenance_details
            description += f"maintenance details: {maintenance_details} "
        if 'spare_part':
            data['spare_part'] = spare_part
            description += f"spare part: {spare_part} "

        if 'repeat_within_six_months':
            data['repeat_within_six_months'] = repeat_within_six_months
            description += f"repeat within six months?: {repeat_within_six_months} "
            print('repeat_within_six_months', repeat_within_six_months)


        result = LogService.check_part_is_parent(repair_order.primary_part)
        
        log = Log(
            username=request.user.username,
            log_type=Log.LogType.MAINTENANCE,
            category_type=Log.CategoryType.ORDER,
            action_type=Log.ActionType.FINALCHECK,
            action='update_repair_order_details',
            payload= json.dumps(data),
            description=description,
            repair_order=repair_order_id,
            parent_stock_code=result['parent_stock_code'],
            parent_part=result['parent_serial_no'],
            part=result['serial_no'],
            stock_code=result['stock_code']
        )
        log.save()

        RepairService.update_repair_order_last_action_date(repair_order_id)
        
        serializer_class = RepairOrderRepairDetailsSerializer
        serializer = serializer_class(instance, data=data, partial=True)
        serializer.is_valid(raise_exception=True)
        serializer.save()

        return Response(serializer.data)
    
    @extend_schema(
        responses={200: PartsSerializer(many=True)},
    )
    @request_data(
        keys=["parent_stock_code", "parent_serial_no","repair_order_id"]
    )
    @action(
        detail=False, methods=["POST"],
        url_name="get_child_parts", schema=AutoDocSchema()
    )
    def get_child_parts(
        self,
        request,
        parent_stock_code,
        parent_serial_no,
        repair_order_id
    ):
        '''
        desc: get all child parts for the parent part
        json:
            parent_stock_code: string
            parent_serial_no: string
        '''
        result_set = RepairService.get_child_parts(
            parent_stock_code,
            parent_serial_no,
            repair_order_id
        )

        serializer = RepairOrderPartSerializer(result_set, many=True)
        return Response(status=ResponseStatus.HTTP_200_OK, data=serializer.data)